﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using ListView = System.Windows.Forms.ListView;

namespace WinFormsApp1.RelationForms
{
    public partial class FormRelationExporter : Form
    {
        public bool ReverseEntittyRelation { get { return this.checkBox1.Checked; } }
        public string SaveFileName { get; private set; }

        private ListView listView1;

        public FormRelationExporter(ListView listView)
        {
            this.listView1 = listView;
            InitializeComponent();
        }
        #region 找到可以定义的列
        private void FormRelationExporter_Load(object sender, EventArgs e)
        {
            List<string> columNames1 = new List<string>();
            List<string> columNames2 = new List<string>();

            List<string> tableCount1 = new List<string>();
            List<string> tableCount2 = new List<string>();
            for (var i = 0; i < this.listView1.Items.Count; i++)
            {
                var ss = listView1.Items[i].Tag as EntityInfo[];
                columNames1.AddRange(ss[0].TableColumn.RefExcel.GetAllColumnNames());
                columNames2.AddRange(ss[1].TableColumn.RefExcel.GetAllColumnNames());
                tableCount1.Add(ss[0].TableColumn.TableName);
                tableCount2.Add(ss[1].TableColumn.TableName);
            }
            tableCount1 = tableCount1.Distinct().ToList();
            tableCount2 = tableCount2.Distinct().ToList();

            if (tableCount1.Count > 1)
            {
                this.groupBox1.Enabled = false;
            }
            else
            {
                this.groupBox1.Text = tableCount1[0]+" 的别名定义";
            }
            if(tableCount2.Count>1)
            {
                this.groupBox2.Enabled = false;
            }
            else
            {
                this.groupBox2.Text = tableCount2[0] + " 的别名定义";
            }
        }
        #endregion

        private void button1_Click(object sender, EventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "*.json|*.json";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                SaveFileName = dlg.FileName;
                this.DialogResult = DialogResult.OK;

                SaveFile(this.listView1);
                this.Close();
            }
        }

        private void SaveFile(ListView listView1)
        {
            Neo4JJSON neo4JJSON = new Neo4JJSON();
            var res1 = new Neo4JData();
            neo4JJSON.results.Add(res1);

            var gd = new Neo4JGraphData();
            res1.data = new List<Neo4JGraphData>() { gd };
            gd.graph = new Neo4JGraph();

            var reverseEntittyRelation = this.ReverseEntittyRelation;

            for (var i = 0; i < this.listView1.Items.Count; i++)
            {
                var ss = listView1.Items[i].Tag as EntityInfo[];

                res1.columns.Add(ss[0].TableColumn.TableName);
                res1.columns.Add(ss[1].TableColumn.TableName);

                gd.graph.nodes.Add(new Neo4JNode()
                {
                    id = ss[0].EntityName,
                    labels = new List<string>() { ss[0].TableColumn.TableName },
                    properties = GetEntityProperity(ss[0],0)
                });
                gd.graph.nodes.Add(new Neo4JNode()
                {
                    id = ss[1].EntityName,
                    labels = new List<string>() { ss[1].TableColumn.TableName },
                    properties = GetEntityProperity(ss[1], 1)
                });
                var pr = new Dictionary<string, string>();
                
                if (reverseEntittyRelation == false)
                {
                    gd.graph.relationships.Add(new Neo4JRelationship()
                    {
                        id = ss[0].ConnectKey,
                        startNode = ss[0].EntityName,
                        endNode = ss[1].EntityName,
                        type = ss[1].TableColumn.TableName,
                        properties = pr
                    });
                    pr.Add("源表", ss[0].TableColumn.TableName);
                    pr.Add("目标表", ss[1].TableColumn.TableName);
                    pr.Add("源表连接列名", ss[0].TableColumn.ColumnName);
                    pr.Add("目标表连接列名", ss[1].TableColumn.ColumnName);
                    pr.Add("连接关键字", ss[0].ConnectKey);
                }
                else
                {
                    gd.graph.relationships.Add(new Neo4JRelationship()
                    {
                        id = ss[1].ConnectKey,
                        startNode = ss[1].EntityName,
                        endNode = ss[0].EntityName,
                        type = ss[0].TableColumn.TableName,
                        properties = pr
                    });
                    pr.Add("源表", ss[1].TableColumn.TableName);
                    pr.Add("目标表", ss[0].TableColumn.TableName);
                    pr.Add("源表连接列名", ss[1].TableColumn.ColumnName);
                    pr.Add("目标表连接列名", ss[0].TableColumn.ColumnName);
                    pr.Add("连接关键字", ss[0].ConnectKey);
                }
            }
            res1.columns = res1.columns.Distinct().ToList();

            var str = JsonConvert.SerializeObject(neo4JJSON);
            File.WriteAllText(SaveFileName, str);
        }

        private Dictionary<string, string> GetEntityProperity(EntityInfo entityInfo,int index)
        {
            Dictionary<string, string> dir = new Dictionary<string, string>();
            var dt = entityInfo.TableColumn.RefExcel.RefDataTable;
            for (var i = 0; i < dt.Columns.Count; i++)
            {
                dir.Add(dt.Columns[i].ColumnName, dt.Rows[entityInfo.RowIndex][i].ToString());
            }

            string formatNameString = "";
            if (index == 0)
            {
                formatNameString = this.textBox1.Text;
            }
            else
            {
                formatNameString = this.textBox2.Text;
            }
            if (string.IsNullOrEmpty(formatNameString) == false)
            {
                string entityName = GetFormatEntityName(formatNameString, dir);
                if (dir.ContainsKey("name") == false)
                {
                    dir.Add("name", entityName);
                }
                else
                {
                    dir["name"] = entityName;
                }
            }

            if (dir.ContainsKey("name") == false)
                dir.Add("name", entityInfo.EntityName);
            return dir;
        }

        private string GetFormatEntityName(string formatStr, Dictionary<string, string> entityProperities)
        {
            while(true)
            {
                var t1 = formatStr.IndexOf('{');
                if (t1 == -1)
                {
                    return formatStr;
                }
                var t2 = formatStr.IndexOf('}', t1);
                var key = formatStr.Substring(t1 + 1, t2 - t1 - 1);
                var fKey = entityProperities.ContainsKey(key) ? entityProperities[key] : "";
                formatStr = formatStr.Substring(0, t1) + fKey + formatStr.Substring(t2 + 1);

            }
            
        }
    }
}
